package com.jrx.anytxn.transaction.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.constant.BankCardConstant;
import com.jrx.anytxn.customer.dto.customer.CustomerRes;
import com.jrx.anytxn.customer.entity.CmCustomerBankcardInfo;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.dto.system.SystemParameterRes;
import com.jrx.anytxn.param.entity.PmMerchantTable;
import com.jrx.anytxn.param.entity.PrCodeTable;
import com.jrx.anytxn.param.entity.PrProductTable;
import com.jrx.anytxn.param.service.partner.IPmMerchantTableService;
import com.jrx.anytxn.param.service.system.ICodeTableService;
import com.jrx.anytxn.param.service.system.ISystemParameterService;
import com.jrx.anytxn.ribbon.config.GrayVersionConfig;
import com.jrx.anytxn.transaction.bean.LoanAbnormalQueueBean;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.dto.loan.CancelOrderQueryRes;
import com.jrx.anytxn.transaction.dto.transactionLog.TlDisbursementLogRes;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.transaction.entity.TlDisbursementLog;
import com.jrx.anytxn.transaction.handler.ILoanHandler;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlDisbursementLogMapper;
import com.jrx.anytxn.transaction.service.IDisbursementLogService;
import com.jrx.anytxn.param.service.system.ISequenceNumberService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 放款支付流水service实现
 *
 * @author : zhenghaopu
 * 2019/10/29
 */
@Service
public class DisbursementLogServiceImpl implements IDisbursementLogService {

    private static final Logger logger = LoggerFactory.getLogger(DisbursementLogServiceImpl.class);

    @Autowired
    private ISegmentService segmentService;
    @Resource
    private ExtTlDisbursementLogMapper extTlDisbursementLogMapper;
    @Autowired
    private IPmMerchantTableService pmMerchantTableService;
    @Autowired
    private GrayVersionConfig grayVersionConfig;
    @Autowired
    ISequenceNumberService sequenceNumberService;
    @Autowired
    private ISystemParameterService iSystemParameterService;
    @Autowired
    private ICodeTableService codeTableService;
    @Resource
    private ILoanHandler iLoanHandler;

    @Override
    public TlDisbursementLog buildTlDisbursementLog(AmLoanMainInfo amLoanMainInfo, CustomerRes customerRes,
                                                    CmCustomerBankcardInfo customerBank, PrProductTable prProductTable, Date businessDate) throws TxnException {
        TlDisbursementLog tlDisbursementLog = new TlDisbursementLog();
        BeanMapping.copy(amLoanMainInfo, tlDisbursementLog);
        try {
            tlDisbursementLog.setId(segmentService.getId(TransBizConstant.TL_DISBURSEMENT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        tlDisbursementLog.setSeqNo(amLoanMainInfo.getSerialNumber());//流水号
        tlDisbursementLog.setAmount(amLoanMainInfo.getLoanAmount());//	汇款金额
        tlDisbursementLog.setPayeeName(customerRes.getFirstLevel().getChineseName());//收款人名称
        tlDisbursementLog.setPayeeAccount(customerBank.getCardNumber());//	收款人账号	　
        String payeeAccountType = TransBizConstant.CARD_TYPE_0;
        if (!BankCardConstant.innerCardFlag(tlDisbursementLog.getPayeeAccount())) {
            payeeAccountType = TransBizConstant.CARD_TYPE_1;
        }
        tlDisbursementLog.setPayeeAccountType(payeeAccountType);//收款账户类型 0 = 本行二类户 1 = 本行借记卡
        tlDisbursementLog.setPayeeBank(customerBank.getBankId());//	收款行号
        tlDisbursementLog.setPayeeBankName(customerBank.getBankName());//收款行名称	　
        tlDisbursementLog.setMobile(customerRes.getSecondLevel().getMobile());//手机
        tlDisbursementLog.setPayeeIdNumber(customerRes.getFirstLevel().getIdNumber());
        tlDisbursementLog.setPayeeIdType(customerRes.getFirstLevel().getIdType());
        String merchantId = amLoanMainInfo.getMerchantId();
        if(TransBizConstant.REMIT_ACCOUT_3.equals(prProductTable.getRemitAccount()) && StringUtils.isNotBlank(merchantId)){
            PmMerchantTable pmMerchantTable = pmMerchantTableService.getByMerchanId(amLoanMainInfo.getTenantId(),merchantId);
            tlDisbursementLog.setPayeeName(pmMerchantTable.getCustomerName());//收款人名称
            tlDisbursementLog.setPayeeAccount(pmMerchantTable.getSettleAcct());//	收款人账号	　
            tlDisbursementLog.setPayeeAccountType(pmMerchantTable.getSettleCardType());//收款账户类型 0 = 本行二类户 1 = 本行借记卡
            tlDisbursementLog.setPayeeBank(pmMerchantTable.getSettleBankId());//	收款行号
            tlDisbursementLog.setPayeeBankName(pmMerchantTable.getSettleBankName());//收款行名称	　
            tlDisbursementLog.setMobile(pmMerchantTable.getMobile());//手机
            tlDisbursementLog.setPayeeIdNumber(pmMerchantTable.getIdNumber());
            tlDisbursementLog.setPayeeIdType(pmMerchantTable.getIdType());
        }

        // 他行或者本行卡内部户设置 623623=本行卡
        String payerType = TransBizConstant.INNER_BANK_DISBURSE_ACCT;
        String payerPeriodType = TransBizConstant.INNER_BANK_DISBURSE_PERIOD_ACCT;
        if (Objects.equals(TransBizConstant.CARD_TYPE_1, payeeAccountType)) {
            //payerType = TransBizConstant.OUTER_BANK_DISBURSE_ACCT;
            payerPeriodType = TransBizConstant.OUTER_BANK_DISBURSE_PERIOD_ACCT;
        }
        //SystemParameterRes payer = iSystemParameterService.findByParamCode(payerType ,amLoanMainInfo.getTenantId());
        SystemParameterRes payerPeriod = iSystemParameterService.findByParamCode(payerPeriodType ,amLoanMainInfo.getTenantId());
        tlDisbursementLog.setPayerAccount(payerPeriod.getParamValue());

        tlDisbursementLog.setPupose(amLoanMainInfo.getLoanUse());//用途	　
        tlDisbursementLog.setPriority(TransBizConstant.LOAN_PRIORITY_REAL_TIME);//加急标志	NORM=批量  HIGH=实时
        tlDisbursementLog.setCurrency(TransBizConstant.CURRENCY_CNY);//交易币种
        tlDisbursementLog.setFeeCode("");// 费项代码	消费信贷为固定值  todo?  目前空
        tlDisbursementLog.setEffectDate(businessDate);//	生效日期 	本行账户使用 当前系统日期
        // 设置放款申请流水号
        tlDisbursementLog.setRefNo(amLoanMainInfo.getSerialNumber());
        tlDisbursementLog.setSumStatus(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_D);
        tlDisbursementLog.setCancelStatus(TransBizConstant.NO_FLAG); //消标志	0=否
        tlDisbursementLog.setBusinessDate(businessDate);//业务日期	　 当前业务日期
        tlDisbursementLog.setCollateDate(businessDate);//对账日期	　当前业务日期
        tlDisbursementLog.setLaunchTime(DateUtils.getBusinessTime(new Date(), businessDate));//交易发起时间	 系统时间
        tlDisbursementLog.setUpdateBy(TransBizConstant.SYS_OPRATE);//	最后更新操作员	　	系统用户 ?
        tlDisbursementLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        tlDisbursementLog.setGrayVersion(grayVersionConfig.getCurrentVersion());
        tlDisbursementLog.setCancelWhenFail(prProductTable.getCancelWhenFail());
        return tlDisbursementLog;
    }

    @Override
    public TlDisbursementLog getTlDisbursementLogByLoanIdAndCusId(String tenantId, String loanId, String customerId) {
        return extTlDisbursementLogMapper.selectDisbursementByCondition(loanId, customerId, tenantId);
    }

    @Override
    public TlDisbursementLogRes getTlDisbursementBySeqNoAndCusId(String tenantId, String seqNo, String customerId) {
        TlDisbursementLog tlDisbursementLog = extTlDisbursementLogMapper.selectTlDisbursementBySeqNoAndCusId(tenantId, customerId, seqNo);
        TlDisbursementLogRes res = BeanMapping.copy(tlDisbursementLog, TlDisbursementLogRes.class);
        return res;
    }

    @Override
    public TxnPage<TlDisbursementLogRes> getDisbursementWithPage(String channel, String customerId, String tenantId, Integer pageNum, Integer pageSize, String seqNo, String beginDate, String endDate) {
        Page<TlDisbursementLog> page = PageHelper.startPage(pageNum, pageSize);
        List<TlDisbursementLog> tlDisbursementLogList = extTlDisbursementLogMapper.selectByCondSelectivePage(tenantId, channel, customerId, seqNo, beginDate, endDate);
        List<TlDisbursementLogRes> res = BeanMapping.copyList(tlDisbursementLogList, TlDisbursementLogRes.class);
        return new TxnPage<>(pageNum, pageSize, page.getTotal(), res);
    }

    /**
     * 分页查询放款异常队列
     * @param abnormalQueueBean 分页查询条件
     * @return
     */
    @Override
    public TxnPage<TlDisbursementLogRes> queryLoanAbnormalQueue(LoanAbnormalQueueBean abnormalQueueBean) {
        Page<TlDisbursementLog> page = PageHelper.startPage(abnormalQueueBean.getPageNum(), abnormalQueueBean.getPageSize());
        // 条件查询放款异常队列
        List<TlDisbursementLog> tlDisbursementLogList = extTlDisbursementLogMapper.selectAbnormalQueueBySumStatus(this.buildqueryParam(abnormalQueueBean));
        List<TlDisbursementLogRes> res = BeanMapping.copyList(tlDisbursementLogList, TlDisbursementLogRes.class);
        return new TxnPage<>(abnormalQueueBean.getPageNum(), abnormalQueueBean.getPageSize(), page.getTotal(), res);
    }

    /**
     * 撤销订单
     *
     *
     * @param businessDate
     * @param operStatus
     * @param seqNo 流水号
     * @param tenantId 租戶id
     * @param nickName 操作人
     * @return
     */
    @Override
    public CancelOrderQueryRes cancelOrder(Date businessDate, String operStatus, String seqNo, String tenantId, String nickName) {
        CancelOrderQueryRes res = new CancelOrderQueryRes();
        res.setSeqNo(seqNo);
        TlDisbursementLog record = extTlDisbursementLogMapper.selectBySeqNoAndTenantId(seqNo, tenantId);
        // 放款流水信息存且判断取消标识为：0-否
        if (!ObjectUtils.isEmpty(record) && TransBizConstant.NO_FLAG.equals(record.getCancelStatus())){
            // PCP端发起撤销或者(CCS异常队列发起撤销且取消状态是未取消的)
            if(TransBizConstant.SYS_OPRATE.equals(nickName) || TransBizConstant.NO_FLAG.equals(record.getCancelStatus())){
                // 更新放款流水表撤销信息，交由取消批次处理撤销流程
                TlDisbursementLog updateLog = new TlDisbursementLog();
                iLoanHandler.getDisSumStatus(operStatus, updateLog);
                updateLog.setId(record.getId());
                updateLog.setTenantId(tenantId);
                updateLog.setSumStatus(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F);
                updateLog.setCancelStatus(TransBizConstant.NO_FLAG);
                updateLog.setCancelWhenFail(TransBizConstant.CANCLE_STATUS_1);
                updateLog.setUpdateBy(nickName);
                updateLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
                // 当成失败处理，后续T24日终汇总会统计
                updateLog.setKeepAccountStatus(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F);
                updateLog.setCustomerId(record.getCustomerId());
                extTlDisbursementLogMapper.updateLog(updateLog);
            }
        }
        res.setSunStatus(TransBizConstant.GATEWAY_DEAL_SUC);
        return res;
    }

    /**
     * 放款结果查询重试
     * @param disId 放款流水表主键id
     * @param nickName 操作人
     */
    @Override
    public void queryRetry(Long disId, String nickName) {
        TlDisbursementLog updateLog = new TlDisbursementLog();
        updateLog.setId(disId);
        updateLog.setQueryMaxCounts(0);// 重置放款结果查询最大次数为0，交由放款结果查询批量处理
        updateLog.setUpdateBy(nickName);
        extTlDisbursementLogMapper.updateLog(updateLog);
    }

    /**
     * 构建异常队列分页查询条件
     * @param abnormalQueueBean
     * @return
     */
    private TlDisbursementLog buildqueryParam(LoanAbnormalQueueBean abnormalQueueBean){
        TlDisbursementLog queryLog = new TlDisbursementLog();
        queryLog.setTenantId(TransBizConstant.DEFAULT_ORG_ID);// 设置租户id
        queryLog.setGrayVersion(grayVersionConfig.getCurrentVersion());// 设置当前发布版本（P生产  G灰度）
        queryLog.setSumStatus(TransBizConstant.PAYMENT_LOG_SUM_STATUS_O);// 设置放款处理中状态
        // 查询放款结果查询最大次数系统配置
        List<PrCodeTable> prCodeTables = codeTableService.findListByCodeIds(TransBizConstant.DISBURSEMENT_QUERY_STATUS_COUNT,
                TransBizConstant.DEFAULT_TENANT_ID);
        queryLog.setQueryMaxCounts(Integer.valueOf(prCodeTables.get(0).getCodeId()));
        BeanMapping.copy(abnormalQueueBean, queryLog);
        return queryLog;
    }
}
